perm filename TEXX.TX[TEX,DEK] blob
sn#841389 filedate 1987-06-14 generic text, type T, neo UTF8
\M2\*. The present implementation has a long ancestry, beginning in the summer
\Y\P\D \37$\\{banner}\S\.{\'This\ is\ TeXX,\ Version\ 2.2\'}$\C{printed when %
\TeX\ starts}\par
\M134\*. A \\{char\_node}, which represents a single character, is the most
\P\D \37$\\{is\_xchar\_node}(\#)\S(\\{font}(\#)=\\{font\_base})$\C{is this %
\\{char\_node} extended?}\par
\P\D \37$\\{bypass\_xchar}(\#)\S$\1\6
\&{if} $\\{is\_xchar\_node}(\#)$ \1\&{then}\5
$\#\K\\{link}(\#)$\2\2\par
\M174\*. Boxes, rules, inserts, whatsits, marks, and things in general that are
\Y\P\4\&{procedure}\1\ \37$\\{short\_display}(\|p:\\{integer})$;\C{prints
highlights of list \|p}\6
\4\&{label} \37\\{done};\6
\4\&{var} \37\|n: \37\\{integer};\C{for replacement counts}\6
\\{ext}: \37\\{integer};\C{amount added to character code by xchar}\2\6
\&{begin} \37$\\{ext}\K0$;\6
\&{while} $\|p>\\{mem\_min}$ \1\&{do}\6
\&{begin} \37\&{if} $\\{is\_char\_node}(\|p)$ \1\&{then}\6
\&{begin} \37\&{if} $\|p\L\\{mem\_end}$ \1\&{then}\6
\&{begin} \37\&{if} $\\{is\_xchar\_node}(\|p)$ \1\&{then}\6
\&{begin} \37$\\{ext}\K256\ast(\\{qo}(\\{character}(\|p)))$;\5
\&{goto} \37\\{done};\6
\&{end};\2\6
\&{if} $\\{font}(\|p)\I\\{font\_in\_short\_display}$ \1\&{then}\6
\&{begin} \37\&{if} $(\\{font}(\|p)<\\{font\_base})\V(\\{font}(\|p)>\\{font%
\_max})$ \1\&{then}\5
$\\{print\_char}(\.{"*"})$\6
\4\&{else} \X267:Print the font identifier for $\\{font}(\|p)$\X;\2\6
$\\{print\_char}(\.{"\ "})$;\5
$\\{font\_in\_short\_display}\K\\{font}(\|p)$;\6
\&{end};\2\6
$\\{print\_ASCII}(\\{ext}+\\{qo}(\\{character}(\|p)))$;\5
$\\{ext}\K0$;\6
\&{end};\2\6
\&{end}\6
\4\&{else} \X175:Print a short indication of the contents of node \|p\X;\2\6
\4\\{done}: \37$\|p\K\\{link}(\|p)$;\6
\&{end};\2\6
\&{end};\par
\M176\*. The \\{show\_node\_list} routine requires some auxiliary subroutines:
\Y\P\4\&{procedure}\1\ \37$\\{print\_font\_and\_char}(\|p:\\{integer})$;%
\C{prints \\{char\_node} data}\6
\4\&{label} \37\\{reswitch};\6
\4\&{var} \37\\{ext}: \37\\{integer};\C{amount added to character code by
xchar, or $-1$}\2\6
\&{begin} \37$\\{ext}\K-1$;\6
\4\\{reswitch}: \37\&{if} $\|p>\\{mem\_end}$ \1\&{then}\5
$\\{print\_esc}(\.{"CLOBBERED."})$\6
\4\&{else} \&{begin} \37\&{if} $\\{is\_xchar\_node}(\|p)$ \1\&{then}\6
\&{begin} \37$\\{ext}\K\\{qo}(\\{character}(\|p))$;\5
$\|p\K\\{link}(\|p)$;\5
\&{goto} \37\\{reswitch};\6
\&{end};\2\6
\&{if} $(\\{font}(\|p)<\\{font\_base})\V(\\{font}(\|p)>\\{font\_max})$ \1%
\&{then}\5
$\\{print\_char}(\.{"*"})$\6
\4\&{else} \X267:Print the font identifier for $\\{font}(\|p)$\X;\2\6
$\\{print\_char}(\.{"\ "})$;\6
\&{if} $\\{ext}<0$ \1\&{then}\5
$\\{print\_ASCII}(\\{qo}(\\{character}(\|p)))$\6
\4\&{else} \&{begin} \37$\\{print\_esc}(\.{"xchar"})$;\5
$\\{print\_hex}(\\{ext}\ast256+\\{qo}(\\{character}(\|p)))$;\6
\&{end};\2\6
\&{end};\2\6
\&{end};\7
\M183\*. \P$\X183\*:Display node \|p\X\S$\6
\&{if} $\\{is\_char\_node}(\|p)$ \1\&{then}\6
\&{begin} \37$\\{print\_font\_and\_char}(\|p)$;\5
$\\{bypass\_xchar}(\|p)$;\6
\&{end}\6
\M208\*. Next are the ordinary run-of-the-mill command codes. Codes that are
\\{min\_internal} or more represent internal quantities that might be
expanded by `\.{\\the}'.
\Y\P\D \37$\\{char\_num}=16$\C{character specified numerically ( \.{\\char} )}%
\par
\P\D \37$\\{xchar\_num}=17$\C{extended character ( \.{\\xchar} )}\par
\P\D \37$\\{math\_char\_num}=18$\C{explicit math code ( \.{\\mathchar} )}\par
\P\D \37$\\{mark}=19$\C{mark definition ( \.{\\mark} )}\par
\M209\*. The next codes are special; they all relate to mode-independent
\M265\*. Many of \TeX's primitives need no \\{equiv}, since they are
$\\{primitive}(\.{"xchar"},\39\\{xchar\_num},\390)$;\par
\M266\*. Each primitive has a corresponding inverse, so that it is possible to
\4\\{xchar\_num}: \37$\\{print\_esc}(\.{"xchar"})$;\par
\M341\*. Now we're ready to take the plunge into \\{get\_next} itself. Parts of
\4\\{exit}: \37\&{if} $\\{tracing\_stats}>2$ \1\&{then}\6
\&{begin} \37$\|k\K\\{trace\_depth}$;\5
$\\{print\_nl}(\.{""})$;\6
\&{while} $\|k>0$ \1\&{do}\6
\&{begin} \37$\\{print}(\.{"\ "})$;\5
$\\{decr}(\|k)$;\6
\&{end};\2\6
$\\{print}(\.{"|"})$;\5
$\\{print\_char}(\.{"\ "})$;\6
\&{if} $\\{cur\_cs}>0$ \1\&{then}\6
\&{begin} \37$\\{print\_cs}(\\{cur\_cs})$;\5
$\\{print\_char}(\.{"="})$;\6
\&{end};\2\6
$\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr})$;\6
\&{end};\2\6
\&{end};\par
\N366\*. \[25] Expanding the next token.
$\\{incr}(\\{trace\_depth})$;\6
\&{if} $\\{tracing\_stats}>2$ \1\&{then}\5
$\\{print}(\.{"\ <x"})$;\2\6
$\\{decr}(\\{trace\_depth})$;\6
\&{if} $\\{tracing\_stats}>2$ \1\&{then}\5
$\\{print\_char}(\.{">"})$;\2\6
\M407\*. In case you are getting bored, here is a slightly less trivial
$\\{incr}(\\{trace\_depth})$;\6
\&{if} $\\{tracing\_stats}>2$ \1\&{then}\6
\&{begin} \37$\\{print}(\.{"\ <\'"})$;\5
$\\{print}(\|s)$;\5
$\\{print\_char}(\.{"\'"})$;\6
\&{end};\2\6
\4\\{exit}: \37$\\{decr}(\\{trace\_depth})$;\6
\&{if} $\\{tracing\_stats}>2$ \1\&{then}\5
$\\{print\_char}(\.{">"})$;\2\6
\&{end};\par
\M435\*. While we're at it, we might as well deal with similar routines that
\4\&{procedure}\1\ \37\\{scan\_xchar\_num};\2\6
\&{begin} \37\\{scan\_int};\6
\&{if} $(\\{cur\_val}<0)\V(\\{cur\_val}>65535)$ \1\&{then}\6
\&{begin} \37$\\{print\_err}(\.{"Bad\ character\ code"})$;\5
$\\{help2}(\.{"An\ \\xchar\ number\ must\ be\ between\ 0\ and\ 255."})$\6
$(\.{"I\ changed\ this\ one\ to\ zero."})$;\5
$\\{int\_error}(\\{cur\_val})$;\5
$\\{cur\_val}\K0$;\6
\&{end};\2\6
\&{end};\7
\M440\*. The \\{scan\_int} routine is used also to scan the integer part of a
$\\{incr}(\\{trace\_depth})$;\6
\&{if} $\\{tracing\_stats}>2$ \1\&{then}\5
$\\{print}(\.{"\ <i"})$;\2\6
$\\{decr}(\\{trace\_depth})$;\6
\&{if} $\\{tracing\_stats}>2$ \1\&{then}\5
$\\{print\_char}(\.{">"})$;\2\6
\M448\*. Constructions like `\.{-\'77 pt}' are legal dimensions, so \\{scan%
$\\{incr}(\\{trace\_depth})$;\6
\&{if} $\\{tracing\_stats}>2$ \1\&{then}\5
$\\{print}(\.{"\ <d"})$;\2\6
$\\{decr}(\\{trace\_depth})$;\6
\&{if} $\\{tracing\_stats}>2$ \1\&{then}\5
$\\{print\_char}(\.{">"})$;\2\6
\M582\*. Here is a function that returns a pointer to a character node for a
\4\&{function}\1\ \37$\\{new\_xchar}(\|f:\\{internal\_font\_number};\,\35\|c:%
\\{integer})$: \37\\{pointer};\6
\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{newly allocated nodes}\2\6
\&{begin} \37$\|q\K\\{new\_character}(\|f,\39\|c\mathbin{\&{mod}}256)$;\6
\&{if} $\|q=\\{null}$ \1\&{then}\5
$\\{new\_xchar}\K\\{null}$\6
\4\&{else} \&{begin} \37$\|p\K\\{get\_avail}$;\5
$\\{font}(\|p)\K\\{font\_base}$;\5
$\\{character}(\|p)\K\\{qi}((\|c\mathbin{\&{div}}256))$;\5
$\\{link}(\|p)\K\|q$;\5
$\\{new\_xchar}\K\|p$;\6
\&{end};\2\6
\&{end};\par
\fi
\M620\*. We ought to give special care to the efficiency of one part of %
\4\\{reswitch}: \37\&{if} $\\{is\_char\_node}(\|p)$ \1\&{then}\6
\&{begin} \37\\{synch\_h};\5
\\{synch\_v};\6
\1\&{repeat} \37\&{if} $\\{is\_xchar\_node}(\|p)$ \1\&{then}\6
\&{begin} \37$\|f\K\\{font}(\\{link}(\|p))$;\6
\&{if} $\\{character}(\|p)=\\{qi}(0)$ \1\&{then}\5
$\|p\K\\{link}(\|p)$;\C{bypass zero extension}\2\6
\&{end}\6
\4\&{else} $\|f\K\\{font}(\|p)$;\2\6
$\|c\K\\{character}(\|p)$;\6
\&{if} $\|f\I\\{dvi\_f}$ \1\&{then}\5
\X621:Change font \\{dvi\_f} to \|f\X;\2\6
\&{if} $\\{is\_xchar\_node}(\|p)$ \1\&{then}\6
\&{begin} \37$\\{dvi\_out}(\\{set1}+1)$;\5
$\\{dvi\_out}(\\{qo}(\|c))$;\5
$\|p\K\\{link}(\|p)$;\5
$\|c\K\\{character}(\|p)$;\6
\&{end}\6
\4\&{else} \&{if} $\|c\G\\{qi}(128)$ \1\&{then}\5
$\\{dvi\_out}(\\{set1})$;\2\2\6
$\\{dvi\_out}(\\{qo}(\|c))$;\6
$\\{cur\_h}\K\\{cur\_h}+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\|c))$;\5
$\|p\K\\{link}(\|p)$;\6
\4\&{until}\5
$\R\\{is\_char\_node}(\|p)$;\2\6
$\\{dvi\_h}\K\\{cur\_h}$;\6
\&{end}\6
\M654\*. The following code is part of \TeX's inner loop; i.e., adding another
\&{begin} \37$\\{bypass\_xchar}(\|p)$;\5
\M841\*. Replacement texts and discretionary texts are supposed to contain
\&{if} $\\{is\_char\_node}(\|v)$ \1\&{then}\6
\&{begin} \37\&{if} $\\{is\_xchar\_node}(\|v)$ \1\&{then}\6
\&{begin} \37$\|v\K\\{link}(\|v)$;\5
$\\{decr}(\|t)$;\C{an xchar counts as two chars}\6
\&{end};\2\6
\&{begin} \37$\\{bypass\_xchar}(\|s)$;\5
\M867\*. The code that passes over the characters of words in a paragraph is
\1\&{repeat} \37$\\{bypass\_xchar}(\\{cur\_p})$;\5
\M871\*. \P$\X871\*:Add the width of node \|s to \\{disc\_width}\X\S$\6
\&{begin} \37$\\{bypass\_xchar}(\|s)$;\5
\M896\*. The first thing we need to do is find the node \\{ha} that contains
\&{if} $\\{hf}=\\{font\_base}$ \1\&{then}\5
\&{goto} \37\\{done1};\C{$\\{is\_xchar\_node}(\|s)$}\2\6
\M899\*. \P$\X899\*:Check that the nodes following \\{hb} permit hyphenation
\&{endcases}\6
\4\&{else} \&{if} $\\{is\_xchar\_node}(\|s)$ \1\&{then}\5
\&{goto} \37\\{done1};\2\2\6
\M1046\*. Here is a list of cases where the user has probably gotten into or
\M1063\*. If a left brace occurs in the middle of a page or paragraph, it
simply
introduces a new level of grouping, and the matching right brace will not have
such a drastic effect. Such grouping affects neither the mode nor the
current list.
\Y\P$\4\X1056:Cases of \\{main\_control} that build boxes and lists\X%
\mathrel{+}\S$\6
\4$\\{non\_math}(\\{left\_brace})$: \37\&{begin} \37$\\{saved}(0)\K\\{line}$;\5
$\\{incr}(\\{save\_ptr})$;\5
$\\{new\_save\_level}(\\{simple\_group})$;\6
\&{end};\C{the line number is saved for possible use in warning message}\6
\4$\\{any\_mode}(\\{begin\_group})$: \37\&{begin} \37$\\{saved}(0)\K\\{line}$;\5
$\\{incr}(\\{save\_ptr})$;\5
$\\{new\_save\_level}(\\{semi\_simple\_group})$;\6
\&{end};\6
\4$\\{any\_mode}(\\{end\_group})$: \37\&{if} $\\{cur\_group}=\\{semi\_simple%
\_group}$ \1\&{then}\6
\&{begin} \37\\{unsave};\5
$\\{decr}(\\{save\_ptr})$;\C{pop unused line number from stack}\6
\&{end}\6
\4\&{else} \\{off\_save};\2\par
\fi
\M1068\*. \P$\X1068\*:Declare the procedure called \\{handle\_right\_brace}\X%
\4\\{simple\_group}: \37\&{begin} \37\\{unsave};\5
$\\{decr}(\\{save\_ptr})$;\C{pop unused line number from stack}\6
\&{end};\6
\M1090\*. \P$\X1056:Cases of \\{main\_control} that build boxes and lists\X%
\M1122\*. We need only two more things to complete the horizontal mode
routines, namely
the \.{\\xchar} and \.{\\accent} primitives.
\Y\P$\4\X1056:Cases of \\{main\_control} that build boxes and lists\X%
\mathrel{+}\S$\6
\4$\\{hmode}+\\{xchar\_num}$: \37\&{begin} \37\\{scan\_xchar\_num};\5
$\\{link}(\\{tail})\K\\{new\_xchar}(\\{cur\_font},\39\\{cur\_val})$;\6
\&{if} $\\{link}(\\{tail})\I\\{null}$ \1\&{then}\5
$\\{tail}\K\\{link}(\\{link}(\\{tail}))$;\2\6
$\\{space\_factor}\K1000$;\6
\&{end};\6
\4$\\{hmode}+\\{accent}$: \37\\{make\_accent};\par
\fi
\M1124\*. \P$\X1124\*:Create a character node \|q for the next character, but
set $\|q\K\\{null}$ if problems arise\X\S$\6
$\|q\K\\{null}$;\5
$\|f\K\\{cur\_font}$;\6
\&{if} $(\\{cur\_cmd}=\\{letter})\V(\\{cur\_cmd}=\\{other\_char})\V(\\{cur%
\_cmd}=\\{char\_given})$ \1\&{then}\5
$\|q\K\\{new\_character}(\|f,\39\\{cur\_chr})$\6
\4\&{else} \&{if} $\\{cur\_cmd}=\\{char\_num}$ \1\&{then}\6
\&{begin} \37\\{scan\_char\_num};\5
$\|q\K\\{new\_character}(\|f,\39\\{cur\_val})$;\6
\&{end}\6
\4\&{else} \&{if} $\\{cur\_cmd}=\\{xchar\_num}$ \1\&{then}\6
\&{begin} \37\\{scan\_xchar\_num};\5
$\|q\K\\{new\_xchar}(\|f,\39\\{cur\_val})$;\6
\&{end}\6
\4\&{else} \\{back\_input}\2\2\2\par
\U section~1123.\fi
\M1125\*. The kern nodes appended here must be distinguished from other kerns,
lest
they be wiped away by the hyphenation algorithm or by a previous line break.
The two kerns are computed with (machine-dependent) \\{real} arithmetic, but
their sum is machine-independent; the net effect is machine-independent,
because the user cannot remove these nodes nor access them via \.{\\lastkern}.
\Y\P$\4\X1125\*:Append the accent with appropriate kerns, then set $\|p\K\|q$\X%
\S$\6
\&{begin} \37$\|t\K\\{slant}(\|f)/\\{float\_constant}(65536)$;\6
\&{if} $\\{is\_xchar\_node}(\|q)$ \1\&{then}\5
$\|i\K\\{char\_info}(\|f)(\\{character}(\\{link}(\|q)))$\6
\4\&{else} $\|i\K\\{char\_info}(\|f)(\\{character}(\|q))$;\2\6
$\|w\K\\{char\_width}(\|f)(\|i)$;\5
$\|h\K\\{char\_height}(\|f)(\\{height\_depth}(\|i))$;\6
\&{if} $\|h\I\|x$ \1\&{then}\C{the accent must be shifted up or down}\6
\&{begin} \37$\|p\K\\{hpack}(\|p,\39\\{natural})$;\5
$\\{shift\_amount}(\|p)\K\|x-\|h$;\6
\&{end};\2\6
$\\{delta}\K\\{round}((\|w-\|a)/\\{float\_constant}(2)+\|h\ast\|t-\|x\ast\|s)$;%
\5
$\|r\K\\{new\_kern}(\\{delta})$;\5
$\\{subtype}(\|r)\K\\{acc\_kern}$;\5
$\\{link}(\\{tail})\K\|r$;\5
$\\{link}(\|r)\K\|p$;\5
$\\{tail}\K\\{new\_kern}(-\|a-\\{delta})$;\5
$\\{subtype}(\\{tail})\K\\{acc\_kern}$;\5
$\\{link}(\|p)\K\\{tail}$;\6
\&{if} $\\{is\_xchar\_node}(\|q)$ \1\&{then}\C{in this case we want to bypass
the xchar part}\6
\&{begin} \37$\\{tail\_append}(\|q)$;\5
$\|p\K\\{link}(\|q)$;\6
\&{end}\6
\4\&{else} $\|p\K\|q$;\2\6
\&{end}\par
\M1147\*. \P$\X1147\*:Let \|d be the natural width of node \|p; if the node is
\&{begin} \37$\\{bypass\_xchar}(\|p)$;\5
\M1335\*. We get to the \\{final\_cleanup} routine when \.{\\end} or \.{\\dump}
\&{while} $\\{cur\_level}>\\{level\_one}$ \1\&{do}\6
\&{begin} \37$\\{print\_nl}(\.{"("})$;\5
$\\{print\_esc}(\.{"end\ occurred\ when\ "})$;\6
\&{case} $\\{cur\_group}$ \1\&{of}\6
\4\\{simple\_group}: \37$\\{print\_char}(\.{"\{"})$;\6
\4\\{semi\_simple\_group}: \37$\\{print\_esc}(\.{"begingroup"})$;\6
\4\&{othercases} \37$\\{confusion}(\.{"endgroup"})$\2\6
\&{endcases};\6
$\\{print}(\.{"\ on\ line\ "})$;\5
\\{unsave};\5
$\\{decr}(\\{save\_ptr})$;\5
$\\{print\_int}(\\{saved}(0))$;\5
$\\{print}(\.{"\ was\ incomplete)"})$;\6
\&{end};\2\6
\&{while} $\\{cond\_ptr}\I\\{null}$ \1\&{do}\6
\&{begin} \37$\\{print\_nl}(\.{"("})$;\5
$\\{print\_esc}(\.{"end\ occurred\ when\ "})$;\5
$\\{print\_cmd\_chr}(\\{if\_test},\39\\{cur\_if})$;\6